package com.lemon.service.impl;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lemon.domain.*;
import com.lemon.domain.dto.OperationsDetailsDto;
import com.lemon.domain.dto.WarehouseOperationsDto;
import com.lemon.mapper.*;
import com.lemon.service.WarehouseOperationsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lemon.service.WarehousingEntryUpService;
import com.lemon.utils.UserThreadLocal;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 仓内作业表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-09-08
 */
@Service
@RequiredArgsConstructor
public class WarehouseOperationsServiceImpl extends ServiceImpl<WarehouseOperationsMapper, WarehouseOperations> implements WarehouseOperationsService {
    private final SkuMapper skuMapper;
    private final WarehouseAreaLocaMapper warehouseAreaLocaMapper;
    private final WarehouseOperationsDetailsMapper warehouseOperationsDetailsMapper;
    private final WarehousingEntryUpMapper warehousingEntryUpMapper;

    @Override
    public List<OperationsDetailsDto> getDetails(Long id) {
        List<WarehouseOperationsDetails> list = warehouseOperationsDetailsMapper.selectList(Wrappers.<WarehouseOperationsDetails>lambdaQuery().eq(WarehouseOperationsDetails::getWarehouseOperationsId, id));
        List<OperationsDetailsDto> detailsDtoList = new ArrayList<>();
        list.forEach(details -> {
            OperationsDetailsDto dto = new OperationsDetailsDto();
            dto.setId(details.getId());
            dto.setSkuId(details.getSkuId());
            dto.setCode(skuMapper.selectById(details.getSkuId()).getCode());
            dto.setTitle(skuMapper.selectById(details.getSkuId()).getTitle());
            dto.setCategory(details.getCategory());
            if (details.getCategory()==1){
                dto.setCount(details.getSourceCount());
            }else {
                dto.setCount(details.getTargetCount());
            }
            dto.setWarehouseAreaLocaName(warehouseAreaLocaMapper.selectById(details.getTargetWarehouseAreaLocaId()).getLocaCode());
            detailsDtoList.add(dto);
        });
        return detailsDtoList;
    }

    @Override
    @Transactional
    public void deleteWarehouse(Long id) {
        baseMapper.deleteById(id);
        warehouseOperationsDetailsMapper.delete(Wrappers.<WarehouseOperationsDetails>lambdaQuery().eq(WarehouseOperationsDetails::getWarehouseOperationsId, id));
    }


    @Override
    @Transactional
    public void confirm(Long id) {
        List<WarehouseOperationsDetails> list = warehouseOperationsDetailsMapper.selectList(Wrappers.<WarehouseOperationsDetails>lambdaQuery().eq(WarehouseOperationsDetails::getWarehouseOperationsId, id));
        list.forEach(details -> {
            if (details.getCategory()==1){
                WarehousingEntryUp entryUp = warehousingEntryUpMapper.selectOne(Wrappers.<WarehousingEntryUp>lambdaQuery().eq(WarehousingEntryUp::getSkuId, details.getSkuId()).eq(WarehousingEntryUp::getWarehouseAreaLocaId, details.getTargetWarehouseAreaLocaId()).last("limit 1"));
                entryUp.setCount(entryUp.getCount()-details.getSourceCount());
                if (entryUp.getCount()==0){
                    warehousingEntryUpMapper.deleteById(entryUp);
                }else  {
                    warehousingEntryUpMapper.updateById(entryUp);
                }
            }
        });
        WarehouseOperations warehouseOperations = baseMapper.selectById(id);
        warehouseOperations.setStatus(2);
        baseMapper.updateById(warehouseOperations);
    }

    @Override
    @Transactional
    public void change(Long id) {
        List<WarehouseOperationsDetails> list = warehouseOperationsDetailsMapper.selectList(Wrappers.<WarehouseOperationsDetails>lambdaQuery().eq(WarehouseOperationsDetails::getWarehouseOperationsId, id));
        list.forEach(details -> {
            if (details.getCategory()==2){
                WarehousingEntryUp entryUp = new WarehousingEntryUp();
                entryUp.setSkuId(Long.valueOf(details.getSkuId()));
                entryUp.setWarehouseId(details.getTargetWarehouseId());
                entryUp.setWarehouseAreaId(details.getTargetWarehouseAreaId());
                entryUp.setWarehouseAreaLocaId(details.getTargetWarehouseAreaLocaId());
                entryUp.setCount(details.getTargetCount());
                entryUp.setStatus(2);
                entryUp.setCreateTime(LocalDateTime.now());
                warehousingEntryUpMapper.insert(entryUp);
            }
        });
        WarehouseOperations warehouseOperations = baseMapper.selectById(id);
        warehouseOperations.setStatus(3);
        baseMapper.updateById(warehouseOperations);
    }


    @Override
    public PageResult getPage(Integer page, Integer pageSize, String jobCode) {
        PageHelper.startPage(page,pageSize);
        List<WarehouseOperations> warehouseOperations = baseMapper.selectList(Wrappers.<WarehouseOperations>lambdaQuery().like(ObjectUtils.isNotEmpty(jobCode), WarehouseOperations::getJobCode, jobCode));
        Page list = (Page) warehouseOperations;
        return new PageResult(list.getTotal(),list.getResult());
    }


    @Override
    @Transactional
    public void add(WarehouseOperationsDto warehouseOperationsDto) {
        WarehouseOperations warehouseOperations = new WarehouseOperations();
        warehouseOperations.setJobCode(UUID.randomUUID().toString().replace("-", ""));
        warehouseOperations.setCategory(warehouseOperationsDto.getCategoryOne());
        warehouseOperations.setStatus(1);
        warehouseOperations.setEmpId(UserThreadLocal.get().getId());
        warehouseOperations.setCreateTime(LocalDateTime.now());
        baseMapper.insert(warehouseOperations);
        warehouseOperationsDto.getDetails().forEach(dto -> {
            WarehouseOperationsDetails details = new WarehouseOperationsDetails();
            details.setSkuId(dto.getSkuId());
            details.setCategory(dto.getCategory());
            if (dto.getCategory()==1){
                details.setSourceCount(dto.getSourceCount());
            }else {
                details.setTargetCount(dto.getTargetCount());
            }
            details.setPrice(skuMapper.selectById(dto.getSkuId()).getPrice().intValue());
            details.setWarehouseOperationsId(warehouseOperations.getId());
            details.setTargetWarehouseAreaLocaId(dto.getTargetWarehouseAreaLocaId());
            WarehouseAreaLoca warehouseAreaLoca = warehouseAreaLocaMapper.selectById(dto.getTargetWarehouseAreaLocaId());
            details.setTargetWarehouseAreaId(warehouseAreaLoca.getWarehouseAreaId());
            details.setTargetWarehouseId(warehouseAreaLoca.getWarehouseId());
            warehouseOperationsDetailsMapper.insert( details);
        });
    }
}
